<template>
  <div>
    <base-modal
      class="material-apply-dialog-container"
      :show.sync="visible"
      :title="title"
      width="900px"
      @closed="reset"
      append-to-body
    >
      <form-builder :is-validate-by-parent="false" :fields="fields" ref="form" :value="form" @update="update" class="warehouse-form">

        <template slot="warehouse" slot-scope="{ field }">
          <form-item :label="$t('common.form.preview.materialReturn.label1')" class="warehouse-form-select">
            <form-select
              :placeholder="field.placeholder" 
              :field="field" 
              :source="warehouseList" 
              v-model="warehouseId" 
              @update="updateWareHouseId" 
              clearable/>
          </form-item>
        </template>

        <template slot="warehouseLocation" slot-scope="{ field }">
          <form-item :label="$t('common.form.preview.materialReturn.label2')" class="warehouse-form-select">
            <form-select
              :placeholder="field.placeholder" 
              :field="field" 
              :source="warehousePositionList" 
              v-model="warehousePositionId" 
              @update="updateWarehousePositionId" 
              clearable/>
          </form-item>
        </template>

      </form-builder>

      <material-table
        ref="materialTable"
        :data="data"
        :columns="columns"
        :card="card"
        :can-select-material="true"
        :waregouse-type="type"
        :warehouse-id="warehouseId"
        :position-id="warehousePositionId"
        @openSnDialog="openSnDialog"
        @input="materialTableInputHandler"
      />

      <div class="btn-group">
        <el-button type="primary" icon="el-icon-plus" plain size="mini" @click="addPart">{{$t('common.form.preview.materialReturn.btn1')}}</el-button>
      </div>

      <div class="dialog-footer" slot="footer">
        <el-button :disabled="pending" @click="visible = false">{{$t('common.base.cancel')}}</el-button>
        <el-button type="primary" :disabled="pending" @click="submit">{{$t('common.base.submit')}}</el-button>
      </div>
      <!-- end 出库方式 -->
    </base-modal>

    <!-- start sn弹窗 -->
    <material-sn-dialog ref="materialSnDialog" />
    <!-- end sn弹窗 -->
  </div>
</template>

<script>
/* api */
import * as WareHouseApi from '@src/api/WareHouseApi';
import * as TaskApi from '@src/api/TaskApi';
/* components */
import MaterialTable from './MaterialTable.vue';
import MaterialSnDialog from './MaterialSnDialog';

export default {
  name: 'material-apply-dialog',
  props: {
    card: {
      type: Object,
      default: () => ({})
    },
    task: {
      type: Object,
      default: () => ({})
    },
    value: {
      type: Array,
      default: () => ([])
    },
    taskId: {
      type: String,
      default: ''
    },
    warrantyStatus: {
      type: String,
      default: ''
    }
  },
  data() {
    return {
      pending: false,
      visible: false,
      data: [],
      params: {},
      outRepertoryType: 1,
      personalRepertory: undefined,
      title: '',
      type: '',
      form: {
        warehouseId: '',
        warehousePositionId: '',
        warehouse: {},
        warehouseLocation: {}
      },
      warehouseList: [],
      warehouseId: '',
      warehouseName: '',
      warehousePositionList: [],
      warehousePositionId: '',
      positionName: '',
      disabled: false
    }
  },
  computed: {
    fields() {
      return [
        {
          formType: 'select',
          fieldName: 'warehouse',
          displayName: this.$t('common.form.preview.materialReturn.label1'),
          placeholder: this.$t('common.form.placeHolder.materialReturn.pla2'),
          isNull: 0,
          disabled: this.disabled,
          setting: {}
        },
        {
          formType: 'select',
          fieldName: 'warehouseLocation',
          displayName: this.$t('common.form.preview.materialReturn.label2'),
          placeholder: this.$t('common.form.placeHolder.materialReturn.pla3'),
          isNull: 0,
          setting: {}
        }
      ]
    },
    /** 备件清单附加组件配置 */
    cardConfig() {
      return JSON.parse(this.card.config || '{}');
    },
    /** 是否开启个人备件库 */
    openPersonalRepertory() {
      return this.outRepertoryType === 1
    },
    /** 显示出库方式 */
    showApproveType() {
      return this.personalRepertory && (this.showOutRepertoryPerson || this.showOutRepertoryDirect);
    },
    /** 显示申领个人备件库 */
    showOutRepertoryPerson() {
      return (this.cardConfig.sparePartWhere || []).indexOf('taskOutRepertoryPerson') > -1;
    },
    /** 显示直接出库 */
    showOutRepertoryDirect() {
      return (this.cardConfig.sparePartWhere || []).indexOf('taskOutRepertoryDirect') > -1;
    },
    /**
    * @description 物料核销弹窗字段
    */
    columns() {
      let fields = [
        {
          displayName: this.$t('common.form.preview.materialReturn.tableLabel1'),
          fieldName: 'materialName',
          width: '110px'
        },
        {
          displayName: this.$t('common.form.preview.materialReturn.colum1'),
          fieldName: 'materialSn',
          width: '80px'
        },
        {
          displayName: this.$t('common.form.preview.materialReturn.tableLabel4'),
          fieldName: 'materialProperty',
          width: '100px'
        },
        {
          displayName: this.$t('common.form.preview.materialReturn.tableLabel5'),
          fieldName: 'isSnManageDict',
          width: '110px'
        },
        {
          displayName: this.$t('common.form.preview.materialReturn.tableLabel6'),
          fieldName: 'salePrice',
          width: '80px'
        },
        {
          displayName: this.$t('common.form.preview.materialReturn.tableLabel1'),
          fieldName: 'materialUnit',
          width: '80px'
        },
        {
          displayName: this.$t('common.form.preview.materialVerifyEliminate.count'),
          fieldName: 'availableNum',
          width: '120px'
        },
        {
          displayName: this.$t('common.form.preview.materialVerifyEliminate.applyNum'),
          fieldName: 'number',
          width: '120px',
          fixed: 'right'
        },
        {
          displayName: this.$t('common.form.preview.materialReturn.tableLabel3'),
          fieldName: 'SN',
          width: '80px',
          fixed: 'right',
        },
        {
          displayName: this.$t('common.base.operation'),
          fieldName: 'action',
          fixed: 'right',
        }
      ]

      // 设置备件名称列宽
      fields.forEach(field => {
        if (field.fieldName == 'name') {
          field.width = '150px';
        }
      })

      return fields;
    }
  },
  methods: {
    getPersonalWarehouseList() {
      // 个人库数据
      WareHouseApi.getPersonalInventoryWarehouse()
        .then((result) => {
          
          if (result?.success) {
            let warehouse = result?.data.warehouse || {}
            let warehousePositionList = result?.data.warehousePositionList || []
            this.warehouseList.push({
              text: warehouse.name,
              value: warehouse.id
            })
            this.warehouseName = this.warehouseList[0].text
            this.warehouseId = this.warehouseList[0].value
            this.warehousePositionList = warehousePositionList.map(item => {
              return {
                text: item.name,
                value: item.id
              }
            })
          }
          
        }).catch(error => {
          console.error(error);
        })
    },
    getPersonalWarehousePositionList() {
      // 仓库 - 仓位
      let params = {
        warehouseId: this.warehouseId
      }
      // TODO 这个接口好像有问题，但是暂时没发现项目中有页面使用该组件，就没改动，后续参考bug 19594。
      WareHouseApi.getWarehousePositionListSearch(params)
        .then((result) => {
          
          if (result?.success) {
            let data = result?.data?.list || []
            this.warehousePositionList = data.map(item => {
              return {
                text: item.name,
                value: item.id
              }
            })
          }

        }).catch(error => {
          console.error(error);
        })
    },
    getWarehouseList() {
      // 仓库
      WareHouseApi.getWarehouseSearch({ enabled: true })
        .then((result) => {
          
          if (result?.success) {
            let data = result?.data || []
            this.warehouseList = data.map(item => {
              return {
                text: item.name,
                value: item.id
              }
            })
          }

        }).catch(error => {
          console.error(error);
        })
    },
    updateWareHouseId({ newValue }) {
      this.warehouseId = newValue
      this.form.warehouse = this.warehouseList.find(item => item.value === newValue) || {}
      this.warehouseName = this.form.warehouse.text
      // 清空仓位
      this.warehousePositionId = ''
      this.getPersonalWarehousePositionList()
    },
    updateWarehousePositionId({ newValue }) {
      this.warehousePositionId = newValue
      this.form.warehouseLocation = this.warehousePositionList.find((item) => item.value == newValue) || {}
      this.positionName = this.form.warehouseLocation.text
    },
    openSnDialog(type) {
      this.$refs.materialSnDialog.open(type)
    },
    /**
    * @description 切换出库方式
    */
    changeOutRepertoryType() {
      this.personalRepertory = {}
    },
    /**
    * @description 打开弹窗
    */
    open(typeMap) {
      let { title, type } = typeMap
      this.title = title
      this.type = type

      this.data = []
      this.warehouseList = []
      this.warehousePositionList = []
      this.warehouseId = ''
      this.warehousePositionId = ''

      this.pending = false
      this.visible = true

      // 个人库
      if(this.type === 'personalLibrary') {
        this.disabled = true
        this.getPersonalWarehouseList()
      }
      // 仓库库
      if(this.type === 'warehouse') {
        this.getWarehouseList()
      }

      this.$nextTick(() => {
        // 默认添加一行数据
        this.addPart()
      })
    },
    /**
    * @description 添加备件
    */
    addPart() {
      this.$refs.materialTable.add();
    },
    /**
    * @description 提交
    * @param {Object} formParams 添加物料
    */
    async submit() {
      // 获取物料数据
      const validateRes = await this.$refs.form.validate();
      if (!validateRes) return;
      
      let tableData = this.getTableData()

      // 获取个人库质保状态
      if(this.type === 'personalLibrary') {
        await this.getMaterialsWarranty(tableData)
      }
      
      let isEmpty = tableData?.length == 1 && !tableData[0]?.id
      if (isEmpty) {
        this.$message.warning(this.$t('common.form.tip.materialReturn.tips8'))
        return
      }
      
      let lackInventory = tableData.some(item => item.id && item.number > item.availableNum)
      if(lackInventory) {
        this.$message.warning(this.$t('common.form.tip.materialVerifyEliminate.tips3'))
        return
      }

      // TODO 国际化待办
      let snNotEnough = tableData.some(item => item.isSnManageDict === '是' && item.snList?.length !== item.number)
      if(snNotEnough) {
        this.$message.warning(this.$t('common.form.tip.materialVerifyEliminate.tips4'))
        return
      }

      // 校验SN是否重复
      let isSnRepeat = tableData.some(item => {

        if(item.isSnManageDict && item.isSnManageDict !== '是') return 

        let result = false
        this.value.forEach(material => {
          
          if(item.materialId == material.materialId) {
            let list = item.snList.concat(material.snList)
            let listRepeat = new Set(list)
            listRepeat = Array.from(listRepeat)
            if(list.length !== listRepeat.length) result = true
          }
        })
        return result
      })
      if(isSnRepeat) {
        this.$message.warning(this.$t('common.form.tip.materialVerifyEliminate.tips5'))
        return
      }
      
      tableData = tableData.filter(item => item.id)
      
      this.$emit('input', {
        data: tableData,
        refsName: 'materialApplyDialog'
      })
    },
    /**
    * @description 获取从个人库添加物料的质保状态
    */
    getMaterialsWarranty(data) {
      let materialIds = data.map(item => item.materialId)
      let param = {
        materialIds,
        taskId: this.taskId
      }
      TaskApi.getMaterialsWarranty(param)
        .then(result => {
          if (result?.success) {
            let materialData = result?.result || []
            materialData.forEach(item => {
              let idx = data.findIndex(material => material.materialId == item.materialId)
              if(idx > -1) {
                this.$set(data[idx], 'warrantyStatus', item.warrantyStatus || this.warrantyStatus)
              }
            })
          }
        }).catch(error => {
          console.error(error);
        })
    },
    getTableData() {
      return this.$refs?.materialTable?.outsideGetTableData() || []
    },
    update({ field, newValue, oldValue }) {
      let { fieldName, displayName } = field
      if (this.$appConfig.debug) {
        console.info(`[FormBuilder] => ${displayName}(${fieldName}) : ${JSON.stringify(newValue)}`);
      }

      this.$set(this.form, fieldName, newValue)
    },
    arrayUnique(arr, name) {
      let hash = {};
      return arr.reduce(function (item, next) {
        hash[next[name]] ? '' : hash[next[name]] = true && item.push(next);
        return item;
      }, []);
    },
    materialTableInputHandler(data) {
      this.data = data
    },
    close() {
      this.visible = false
      this.reset()
    },
    reset() {
      this.initForm()
      this.initTableData()
    },
    initForm() {
      this.form = {
        warehouse: {},
        warehouseLocation: {}
      }
      this.form.warehouseId = ''
      this.form.warehousePositionId = ''
      this.disabled = false
    },
    initTableData() {
      this.$refs.materialTable.outsideSetTableData()
    }
  },
  components: {
    [MaterialTable.name]: MaterialTable,
    [MaterialSnDialog.name]: MaterialSnDialog
  }
}
</script>

<style lang="scss" scoped>
.material-apply-dialog-container {
  ::v-deep .base-modal-body {
    padding: 16px 0 !important;
  }

  .material-apply-method-panel {
    padding: 0 16px 16px;

    .el-radio {
      color: $text-color-regular;
      margin-right: 24px;
    }
  }

  .btn-group {
    text-align: center;
    margin-top: 16px;
    padding: 0 12px !important;

    .el-button {
      padding: 8px;
      border-radius: 4px;
    }
  }

  .warehouse-form {
    display: flex;
    justify-content: space-between;
    .warehouse-form-select {
      margin-right: 40px !important;
    }
  }
  
}
::v-deep .form-item label {
  width: 80px !important;
}
</style>